<?php
/**
 * Ly - 基础函数库
 *
 * 系统基础函数，可独立于系统本身环境运行
 *
 * Copyright (c) 2013 YinHailin All rights reserved.
 * @Author: YinHailin
 * @Authorize: Boren Network
 * @Created by YinHailin at 2013-11-01
 */

defined('LY_VERSION') or exit();

/* 过滤表单中的表达式 */
function filter_exp(&$value){
  if (in_array(strtolower($value), array('exp', 'or'))) {
    $value .= ' ';
  }
}

/*
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @return mixed
 */
function get_client_ip($type = 0) {
  $type = $type ? 1 : 0;
  static $ip = NULL;
  if ($ip !== NULL) return $ip[$type];
  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $pos = array_search('unknown', $arr);
    if (false !== $pos) unset($arr[$pos]);
    $ip = trim($arr[0]);
  } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif (isset($_SERVER['REMOTE_ADDR'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
  }
  // IP地址合法验证
  $long = sprintf("%u", ip2long($ip));
  $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
  return $ip[$type];
}

/*
 * 字符串命名风格转换
 + type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 * @param string $name 字符串
 * @param integer $type 转换类型
 * @return string
 */
function parse_name($name, $type = 0) {
  if ($type) {
    return ucfirst(preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name));
  } else {
    return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
  }
}

/*
 * 发送HTTP状态
 * @param integer $code 状态码
 */
function send_http_status($code) {
  static $_status = array(
    // Success 2xx
    200 => 'OK',
    // Redirection 3xx
    301 => 'Moved Permanently',
    302 => 'Moved Temporarily ',  // 1.1
    // Client Error 4xx
    400 => 'Bad Request',
    403 => 'Forbidden',
    404 => 'Not Found',
    // Server Error 5xx
    500 => 'Internal Server Error',
    503 => 'Service Unavailable',
  );
  if (isset($_status[$code])) {
    header('HTTP/1.1 '.$code.' '.$_status[$code]);
    // 确保FastCGI模式下正常
    header('Status:'.$code.' '.$_status[$code]);
  }
}

/*
 * 去除代码中的空白和注释
 * @param string $content 代码内容
 * @return string
 */
function strip_whitespace($content) {
  $stripStr = '';
  //分析php源码
  $token = token_get_all($content);
  $lastSpace = false;
  $j = count($token);
  for ($i = 0; $i < $j; $i++) {
    if (is_string($token[$i])) {
      $lastSpace = false;
      $stripStr .= $token[$i];
    } else {
      switch ($token[$i][0]) {
        //过滤各种PHP注释
        case T_COMMENT:
        case T_DOC_COMMENT:
          break;
        //过滤空格
        case T_WHITESPACE:
          if (!$lastSpace) {
            $stripStr .= ' ';
            $lastSpace = true;
          }
          break;
        case T_START_HEREDOC:
          $stripStr .= $token[$i][1]."\n";
          break;
        case T_END_HEREDOC:
          $stripStr .= $token[$i][1].";\n";
          for ($k = $i+1; $k < $j; $k++) {
            if (is_string($token[$k]) && $token[$k] == ';') {
              $i = $k;
              break;
            } elseif ($token[$k][0] == T_CLOSE_TAG) {
              break;
            }
          }
          break;
        default:
          $lastSpace = false;
          $stripStr .= $token[$i][1];
      }
    }
  }
  return $stripStr;
}

/*
 * 根据PHP各种类型变量生成唯一标识号
 * @param mixed $mix 变量
 * @return string
 */
function to_guid_string($mix) {
  if (is_object($mix) && function_exists('spl_object_hash')) {
    return spl_object_hash($mix);
  } elseif (is_resource($mix)) {
    $mix = get_resource_type($mix) . strval($mix);
  } else {
    $mix = serialize($mix);
  }
  return md5($mix);
}

/*
 * 删除文件夹
 * @param string $dir 路径
 * @return string
 */
function dir_delete($dir) {
  $dir = dir_path($dir);
  if (!is_dir($dir)) {
    return false;
  }
  $list = glob($dir . '*');
  foreach ($list as $file) {
    is_dir($file) ? dir_delete($file) : unlink($file);
  }
  return rmdir($dir);
}

/*
 * 校正路径
 * @param string $path 路径
 * @return string
 */
function dir_path($path) {
  $path = str_replace('\\', '/', $path);
  if (substr($path, -1) != '/') { $path = $path . '/';}
  return $path;
}

/*
 * 对二维数组获得指定值的一维索引或键名
 * + 匹配到一个值之后便不再执行
 * @param array $array 二维数组
 * @param strings $search 需要查找的二维值
 * @return string
 */
function two_array_search($array, $search) {
  foreach ($array as $key => $value) {
    if (in_array($search, $value)) {
      return $key;
    }
  }
  return false;
}